package itsm.isperp.module.service.slm;

import itsm.isperp.framework.core.context.ContextHolder;
import itsm.isperp.framework.data.dialect.DialectFactory;
import itsm.isperp.framework.domain.IUser;
import itsm.isperp.framework.service.BaseService;
import itsm.isperp.framework.template.Template;
import itsm.isperp.framework.template.TemplateException;
import itsm.isperp.framework.utils.DateUtils;
import itsm.isperp.framework.web.response.ResultMessage;
import itsm.isperp.module.entity.app.AppMessage;
import itsm.isperp.module.entity.db.DbEntityFieldControl;
import itsm.isperp.module.entity.slm.SlmServiceAgreement;
import itsm.isperp.module.repository.slm.SlmServiceAgreementMapper;
import itsm.isperp.module.service.app.AppMessageService;
import itsm.isperp.module.utils.MessageUserUtils;
import itsm.isperp.workflow.cmd.JumpCmd;

import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.activiti.engine.ProcessEngine;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.StopWatch;
import org.joda.time.DateTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jdbc.support.DatabaseType;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

@Service
public class SlmServiceAgreementService extends
    BaseService<SlmServiceAgreement> {

  public static final Logger logger = LoggerFactory
      .getLogger(SlmServiceAgreementService.class);

  @Autowired
  protected SlmServiceAgreementMapper slmServiceAgreementMapper;

  @Autowired
  protected JdbcTemplate jdbcTemplate;

  @Override
  public SlmServiceAgreementMapper getRepository() {
    return this.slmServiceAgreementMapper;
  }

  @Autowired
  ProcessEngine processEngine;

  @Override
  public ResultMessage delete(String id) {
    Assert.notNull(id, "id不能为空");

    SlmServiceTargetService slmServiceTargetService = ContextHolder
        .getSpringBean("slmServiceTargetService");

    slmServiceTargetService.deleteByAgreementId(id);

    this.getRepository().deleteByClass(id, SlmServiceAgreement.class);
    return ResultMessage.success();
  }

  /**
   * 根据项目id删除所有管理的服务协议（促发级联删除写一些的目标及提醒设定以及提醒人员）
   * 
   * @param projectId
   */
  public void deleteByProjectId(String projectId) {
    Assert.notNull(projectId, "projectId不能为空");

    SlmAlarmSettingService slmAlarmSettingService = ContextHolder
        .getSpringBean("slmAlarmSettingService");

    slmAlarmSettingService.deleteByProjectId(projectId);
    this.getRepository().deleteByProjectId(projectId);
  }

  /**
   * 
   * @param agreementId
   */
  public List<DbEntityFieldControl> getSlmCalculateFieldControl(String id) {
    return this.slmServiceAgreementMapper.findSlmCalculateFieldControl(id);
  }

  public DbEntityFieldControl findSlmMonitorFieldControl(String id) {
    return this.slmServiceAgreementMapper.findSlmMonitorFieldControl(id);
  }

  /**
   * 
   * @param agreementId
   */
  public List<Map<String, Object>> matchSlmList(String projectId,
      String processKey, String businessKey) {

    return this.slmServiceAgreementMapper.callSpSlmMatch(projectId, processKey,
        businessKey);

  }

  public static void startSlmByName(String id, String tableName,
      String targetName,String projectId) throws ParseException {
    
    JdbcTemplate jdbcTemplate=ContextHolder.getSpringBean("jdbcTemplate");
    
    String argeement_id = null;
    String argeement_name = null;
    String use_project_calendar = null;
    
    String nowSql = "", uuid = "";
    if (DialectFactory.getDatabaseType() == DatabaseType.MYSQL) {
      nowSql = "now()";
      uuid = "uuid()";
    } else {
      nowSql = "sysdate";
      uuid = "sys_guid()";
    }

    String getAgreement = "SELECT id,name,scope_sql,use_project_calendar FROM slm_service_agreement WHERE (EXISTS (SELECT 1 FROM slm_project_agreement WHERE project_id='"
        + projectId
        + "' AND slm_agreement_id=slm_service_agreement.id)) AND SLM_STATUS='启用' order by project_id desc";

    List<Map<String,Object>> list = jdbcTemplate.queryForList(getAgreement);
    String ss = null;
    for (Map<String, Object> m : list) {
      String scope_sql = "";
      if (m.get("scope_sql") != null)
        scope_sql = m.get("scope_sql").toString();
      if (StringUtils.isNotEmpty(scope_sql)) {
        ss = "SELECT  id c_count FROM " + tableName + " c WHERE id='" + id
            + "' AND " + scope_sql;
      } else {
        ss = "SELECT  id c_count FROM " + tableName + " c WHERE id='" + id
            + "'";
      }
      try {
        jdbcTemplate.queryForObject(ss, String.class);
        argeement_id = m.get("id").toString();
        argeement_name = m.get("name").toString();
        use_project_calendar = m.get("use_project_calendar").toString();
        break;
      } catch (Exception ex) {
        logger.info("加载服务失败,id[" + id + "]");
      }

    }

    jdbcTemplate
        .update("UPDATE  slm_busobject_service_target SET stoped=1,actual_value=current_value,finish_time="
            + nowSql + " WHERE apply_object_id='" + id + "'");

    List<Map<String, Object>> targets = jdbcTemplate
        .queryForList(
            "SELECT id,target,target_sec,target_da,target_db FROM slm_service_target WHERE agreement_id=? and name=?",
            argeement_id,targetName);

    List<Object[]> batchArgs = new ArrayList<>();
    double target_sec_all = 0;
    for (Map<String, Object> map : targets) {
      String targetId = map.get("id").toString(), target = map.get("target")
          .toString(), target_da = "", target_db = "";

      int target_sec = Integer.parseInt(map.get("target_sec").toString());

      target_sec_all += target_sec;

      Object[] objs = new Object[12];
      objs[0] = targetId;
      objs[1] = target;
      objs[2] = target_sec;
      objs[3] = "0:0";
      objs[4] = "正常";
      objs[5] = 0;
      objs[6] = 0;
      objs[7] = 0;
      objs[8] = id;
      objs[9] = argeement_id;
      objs[10] = target_da;
      objs[11] = target_db;
      batchArgs.add(objs);
    }
    target_sec_all = target_sec_all;
    jdbcTemplate
        .batchUpdate(
            "INSERT INTO slm_busobject_service_target (id,service_target_id,plan_value,plan_value_sec,current_value,start_time,update_time,status,started,stoped,cumulative_time,apply_object_id,slm_id,target_da,target_db )VALUES("
                + uuid
                + ",?,?,?,?,"
                + nowSql
                + ","
                + nowSql
                + ",?,?,?,?,?,?,?,?)", batchArgs);

    if ("0".equals(use_project_calendar)
        || "false".equals(use_project_calendar)) {
      String up = "UPDATE " + tableName + " SET slm_id='" + argeement_id
          + "',slm_name='" + argeement_name + "',deadline=" + nowSql + "+("
          + (target_sec_all * 1000) + "/86400000),sla_status=0 WHERE id='" + id
          + "'";

      jdbcTemplate.update(up);

    } else {

      Map<String, Object> calMap = jdbcTemplate
          .queryForMap("SELECT b.*,"
              + nowSql
              + " now_time FROM proj_project a INNER JOIN app_calendar_config b ON a.app_calendar_config_id=b.id WHERE a.id='"
              + projectId + "'");

      String app_calendar_config_id = calMap.get("id").toString();
      Date now_date = (Date) calMap.get("now_time");

      long am_begin = ((Date) calMap.get("am_begin")).getTime();
      long am_end = ((Date) calMap.get("am_end")).getTime();

      long pm_begin = ((Date) calMap.get("pm_begin")).getTime();
      long pm_end = ((Date) calMap.get("pm_end")).getTime();

      Date fiDate = SlmServiceAgreementManualService.getDeadline(argeement_id,
          target_sec_all * 1000, app_calendar_config_id, am_begin, am_end,
          pm_begin, pm_end, now_date, nowSql, jdbcTemplate);
      String up = "UPDATE " + tableName + " SET slm_id='" + argeement_id
          + "',slm_name='" + argeement_name
          + "',sla_status=0,deadline=?  WHERE id='" + id + "'";

      jdbcTemplate.update(up, fiDate);
    }

  }

  /**
   * 在事件单流程中调用
   * 
   * @param id
   * @param tableName
   * @param userId
   * @param serviceCategoryId
   * @param projectId
   * @param jdbcTemplate
   */
  public static void startSlm(String id, String tableName, String userId,
      String serviceCategoryId, String projectId, JdbcTemplate jdbcTemplate) {

    if (userId == null) {
      return;
    }

    String nowSql = "", uuid = "";
    if (DialectFactory.getDatabaseType() == DatabaseType.MYSQL) {
      nowSql = "now()";
      uuid = "uuid()";
    } else {
      nowSql = "sysdate";
      uuid = "sys_guid()";
    }

    try {
      String getUser = "SELECT type FROM app_user WHERE id='" + userId + "'";

      String ut = jdbcTemplate.queryForObject(getUser, String.class);

      // String s = "1=1  AND ( user_type='" + ut
      // + "' ) AND (service_category_id='" + serviceCategoryId
      // + "' )";
      //
      //
      if (StringUtils.isEmpty(ut)) {
        ut = "";
      }
      String s = " AND scope_sql LIKE '%" + ut + "%' AND scope_sql LIKE '%"
          + serviceCategoryId + "%'";

      String getAgreement = "SELECT id,name,use_project_calendar FROM slm_service_agreement WHERE (EXISTS (SELECT 1 FROM slm_project_agreement WHERE project_id='"
          + projectId
          + "' AND slm_agreement_id=slm_service_agreement.id)) AND SLM_STATUS='启用' "
          + s + " order by project_id desc";

      List<Map<String, Object>> list = jdbcTemplate.queryForList(getAgreement);

      String argeement_id = null;
      String argeement_name = null;
      String use_project_calendar = null;
      if (list.size() == 1) {
        Map<String, Object> m = list.get(0);

        // slm_service_target
        argeement_id = m.get("id").toString();
        argeement_name = m.get("name").toString();
        use_project_calendar = m.get("use_project_calendar").toString();
      } else {
        // 系统的服务目录
        getAgreement = "SELECT id,name,scope_sql,use_project_calendar FROM slm_service_agreement WHERE (EXISTS (SELECT 1 FROM slm_project_agreement WHERE project_id='"
            + projectId
            + "' AND slm_agreement_id=slm_service_agreement.id)) AND SLM_STATUS='启用' order by project_id desc";

        list = jdbcTemplate.queryForList(getAgreement);
        String ss = null;
        for (Map<String, Object> m : list) {
          String scope_sql = "";
          if (m.get("scope_sql") != null)
            scope_sql = m.get("scope_sql").toString();
          if (StringUtils.isNotEmpty(scope_sql)) {
            ss = "SELECT  id c_count FROM " + tableName + " c WHERE id='" + id
                + "' AND " + scope_sql;
          } else {
            ss = "SELECT  id c_count FROM " + tableName + " c WHERE id='" + id
                + "'";
          }
          try {
            jdbcTemplate.queryForObject(ss, String.class);
            argeement_id = m.get("id").toString();
            argeement_name = m.get("name").toString();
            use_project_calendar = m.get("use_project_calendar").toString();
            break;
          } catch (Exception ex) {
            logger.info("加载服务失败,id[" + id + "]");
          }

        }
      }

      if (argeement_id == null) {
        return;
      }

      jdbcTemplate
          .update("UPDATE  slm_busobject_service_target SET stoped=1,actual_value=current_value,finish_time="
              + nowSql + " WHERE apply_object_id='" + id + "'");

      List<Map<String, Object>> targets = jdbcTemplate
          .queryForList(
              "SELECT id,target,target_sec,target_da,target_db FROM slm_service_target WHERE agreement_id=?",
              argeement_id);

      List<Object[]> batchArgs = new ArrayList<>();
      double target_sec_all = 0;
      for (Map<String, Object> map : targets) {
        String targetId = map.get("id").toString(), target = map.get("target")
            .toString(), target_da = "", target_db = "";

        int target_sec = Integer.parseInt(map.get("target_sec").toString());

        target_sec_all += target_sec;

        Object[] objs = new Object[12];
        objs[0] = targetId;
        objs[1] = target;
        objs[2] = target_sec;
        objs[3] = "0:0";
        objs[4] = "正常";
        objs[5] = 0;
        objs[6] = 0;
        objs[7] = 0;
        objs[8] = id;
        objs[9] = argeement_id;
        objs[10] = target_da;
        objs[11] = target_db;
        batchArgs.add(objs);
      }
      target_sec_all = target_sec_all;
      jdbcTemplate
          .batchUpdate(
              "INSERT INTO slm_busobject_service_target (id,service_target_id,plan_value,plan_value_sec,current_value,start_time,update_time,status,started,stoped,cumulative_time,apply_object_id,slm_id,target_da,target_db )VALUES("
                  + uuid
                  + ",?,?,?,?,"
                  + nowSql
                  + ","
                  + nowSql
                  + ",?,?,?,?,?,?,?,?)", batchArgs);

      if ("0".equals(use_project_calendar)
          || "false".equals(use_project_calendar)) {
        String up = "UPDATE " + tableName + " SET slm_id='" + argeement_id
            + "',slm_name='" + argeement_name + "',deadline=" + nowSql + "+("
            + (target_sec_all * 1000) + "/86400000),sla_status=0 WHERE id='"
            + id + "'";

        jdbcTemplate.update(up);

      } else {

        Map<String, Object> calMap = jdbcTemplate
            .queryForMap("SELECT b.*,"
                + nowSql
                + " now_time FROM proj_project a INNER JOIN app_calendar_config b ON a.app_calendar_config_id=b.id WHERE a.id='"
                + projectId + "'");

        String app_calendar_config_id = calMap.get("id").toString();
        Date now_date = (Date) calMap.get("now_time");

        long am_begin = ((Date) calMap.get("am_begin")).getTime();
        long am_end = ((Date) calMap.get("am_end")).getTime();

        long pm_begin = ((Date) calMap.get("pm_begin")).getTime();
        long pm_end = ((Date) calMap.get("pm_end")).getTime();

        Date fiDate = SlmServiceAgreementManualService.getDeadline(
            argeement_id, target_sec_all * 1000, app_calendar_config_id,
            am_begin, am_end, pm_begin, pm_end, now_date, nowSql, jdbcTemplate);
        String up = "UPDATE " + tableName + " SET slm_id='" + argeement_id
            + "',slm_name='" + argeement_name
            + "',sla_status=0,deadline=?  WHERE id='" + id + "'";

        jdbcTemplate.update(up, fiDate);
      }

    } catch (Exception ex) {
      logger.error(ex.getMessage(), ex);
    }

  }

  public static void stopSlmTargetByName(String id, String targerName) {
    JdbcTemplate jdbcTemplate = ContextHolder.getSpringBean("jdbcTemplate");
    String nowSql;
    if (DialectFactory.getDatabaseType() == DatabaseType.MYSQL) {
      nowSql = "now()";
    } else {
      nowSql = "sysdate";
    }
    String sql = "UPDATE slm_busobject_service_target a INNER JOIN slm_service_target b  ON a.service_target_id=b.id SET a.stoped=1,a.finish_time="
        + nowSql
        + ",a.actual_value=a.current_value"
        + " WHERE a.apply_object_id='"
        + id
        + "' AND b.NAME='"
        + targerName
        + "'";

    jdbcTemplate.update(sql);

  }

  public static void stopSlmTarget(String id, String targetDb,
      JdbcTemplate jdbcTemplate) {
    String nowSql;
    if (DialectFactory.getDatabaseType() == DatabaseType.MYSQL) {
      nowSql = "now()";
    } else {
      nowSql = "sysdate";
    }

    String sql = ("UPDATE slm_busobject_service_target a SET  stoped=1,finish_time="
        + nowSql
        + ",actual_value=current_value"
        + "  WHERE a.apply_object_id='"
        + id
        + "' AND "
        + "  TARGET_DB='"
        + targetDb + "'");

    jdbcTemplate.update(sql);

  }

  public static void stopSlm(String id, String tableName,
      JdbcTemplate jdbcTemplate) {

    String nowSql;
    if (DialectFactory.getDatabaseType() == DatabaseType.MYSQL) {
      nowSql = "now()";
    } else {
      nowSql = "sysdate";
    }

    // 关闭计算
    String stopSql = "UPDATE slm_busobject_service_target a"
        + " SET stoped=1, finish_time=" + nowSql
        + ", actual_value=current_value "
        + "  WHERE  a.stoped=0  AND  a.apply_object_id = '" + id + "' ";

    jdbcTemplate.update(stopSql);
    // 对于没有加载slm的设置为0
    String slmSql = "UPDATE " + tableName + " SET slm_id=0  WHERE id = '" + id
        + "' AND slm_id  IS NULL ";
    jdbcTemplate.update(slmSql);
  }

  // private static void getElapsedWorktime(String id, JdbcTemplate
  // jdbcTemplate) {
  //
  // // 取得工作日
  // String sql =
  // "SELECT a.id,a.start_time,a.update_time,a.slm_id,b.project_id,b.use_project_calendar,c.app_calendar_config_id"
  // + " FROM slm_busobject_service_target a "
  // + " INNER JOIN slm_service_agreement b ON a.slm_id=b.id "
  // + " INNER JOIN proj_project p ON b.project_id=p.id"
  // + "  WHERE a.apply_object_id='" + id + "' AND stoped=0";
  //
  // List<Map<String, Object>> list = jdbcTemplate.queryForList(sql);
  //
  // if (list.size() > 0) {
  //
  // boolean use_project_calendar = false;
  //
  // // 如果是按照工作日历
  // if (use_project_calendar) {
  // // 取得工作日里下的工作时间
  // String app_calendar_config_id = list.get(0)
  // .get("app_calendar_config_id").toString();
  //
  // String updateSql = "UPDATE slm_busobject_service_target "
  // + " SET finish_time=?,stoped=1,actual_value=current_value,";
  //
  // // 对于没有关闭的slm
  // for (Map<String, Object> m : list) {
  // String start_time = "", update_time = "";
  //
  // // 查询总天数
  // // 如果总天数为0则返回0
  // String getDateSql =
  // "SELECT * FROM app_calendar_day a WHERE app_calendar_config_id='"
  // + app_calendar_config_id
  // + "' AND calendar_date BETWEEN to_date('"
  // + start_time
  // + "') AND to_date('"
  // + update_time
  // + "')";
  //
  // List<Map<String, Object>> dates = jdbcTemplate
  // .queryForList(getDateSql);
  // int count = dates.size();
  //
  // // 如果总天数大于0
  // // 则获取开始时间和介绍时间
  // // 1.取得开始时间和结束时间所在的日期是否为工作日期
  // // 2.如果总天数为2
  // // 3.如果总天数为1
  // // 4.如果总天数大于2
  //
  // }
  //
  // // 循环所有工作日，计算每个的实际工作时间，如果存在异常则将更新对象是否异常则更新对象表
  //
  // } else {// 如果是7×24小时则直接计算了
  // // 直接算出各个的时间
  // }
  // }
  //
  // }

  // private static String appendInsertBusObject(String project_id,
  // String argeement_id, String scope_sql,
  // String apply_object_table_name, String nowSql, String uuid,
  // boolean hasProcessId) {
  //
  // StringBuilder slm_busobject_service_target = new StringBuilder();
  //
  // // 插入数据到监控表
  // slm_busobject_service_target
  // .append("INSERT INTO slm_busobject_service_target (id,service_target_id,plan_value,plan_value_sec,current_value,start_time,update_time,status,started,stoped,cumulative_time,apply_object_id,slm_id,target_da,target_db )");
  // slm_busobject_service_target.append(" SELECT  " + uuid
  // + " ,st.id,st.target,st.target_sec,'0:0'," + nowSql + ","
  // + nowSql + ",'正常',0,0,0, c.id,'" + argeement_id
  // + "',st.target_da,st.target_db FROM ");
  // slm_busobject_service_target.append(apply_object_table_name);
  // slm_busobject_service_target
  // .append(" c  INNER  JOIN slm_service_target st ON ");
  // slm_busobject_service_target.append(" st.agreement_id='");
  // slm_busobject_service_target.append(argeement_id);
  // slm_busobject_service_target.append("' ");
  // slm_busobject_service_target.append("  WHERE c.project_id='")
  // .append(project_id)
  // .append("' AND c.status<>'已关闭'  AND c.slm_id  IS NULL ");
  // if (hasProcessId) {
  // slm_busobject_service_target
  // .append("  AND c.process_id IS NOT NULL ");
  // }
  //
  // if (StringUtils.isNotEmpty(scope_sql)) {
  // slm_busobject_service_target.append(" AND (");
  // slm_busobject_service_target.append(scope_sql).append("  ) ");
  // }
  //
  // return slm_busobject_service_target.toString();
  //
  // }

  public List<Map<String, Object>> findAllAgreement() {

    List<Map<String, Object>> allList = null;

    if (DialectFactory.getDatabaseType() == DatabaseType.MYSQL) {
      allList = slmServiceAgreementMapper.findAllSlmElaspsed();
    } else {

      DateTime dt = DateTime.now();
      String t = "1970-01-01 " + dt.toLocalTime().toString("HH:mm:SS");

      try {
        allList = slmServiceAgreementMapper.findAllSlmElaspsedForOracle(
            DateUtils.parseDateTime(t), dt.toLocalDate().toDate());
      } catch (ParseException e) {
        allList = new ArrayList<>();
      }
    }

    return allList;

  }

  // 此次以后优化，考虑增加对缓存及mapredure的使用，优化其性能
  public void elapsedWorktime(long interval) {
    // 找到符合的项目的所有的服务协议
    List<Map<String, Object>> allList = findAllAgreement();

    int size = allList.size();
    if (size <= 0) {
      return;
    }

    List<String> slm_busobject_service_target_sql = new ArrayList<>();

    String apply_object_rely_table_name = null;
    String apply_object_rely_table_name2 = null;

    String apply_object_slm_monitor_column = null;

    String nowSql = null, uuid = null;
    if (DialectFactory.getDatabaseType() == DatabaseType.MYSQL) {
      nowSql = "now()";
      uuid = "uuid()";

    } else {
      nowSql = "sysdate";
      uuid = "sys_guid()";
    }

    String argeement_ids = "";

    for (int i = 0; i < size; i++) {

      Map<String, Object> map = allList.get(i);
      String argeement_id = (String) map.get("id");
      // String project_id = (String) map.get("project_id");
      // String scope_sql = (String) map.get("scope_sql");
      // String apply_object_table_name = (String) map.get("table_name");
      // String elapsedType = (String) map.get("elapsed_type");

      apply_object_rely_table_name = (String) map.get("slm_rely_table_name");
      apply_object_slm_monitor_column = (String) map.get("slm_monitor_column");

      // 如果是系统服务目录的话
      // if ("SYS".equals(elapsedType))
      // slm_busobject_service_target_sql.add(appendInsertBusObject(
      // project_id, argeement_id, scope_sql,
      // apply_object_table_name, nowSql, uuid, true));

      if (i == 0) {
        argeement_ids += "'" + argeement_id + "'";
      } else {
        argeement_ids += ",'" + argeement_id + "'";
      }

      // 避免重复运行更新（理论只有一次，即事件管理）
      if (apply_object_rely_table_name != null
          && !apply_object_rely_table_name
              .equals(apply_object_rely_table_name2)) {

        apply_object_rely_table_name2 = apply_object_rely_table_name;
        apply_object_slm_monitor_column = (String) map
            .get("slm_monitor_column");

        // if (DialectFactory.getDatabaseType() == DatabaseType.MYSQL) {
        // // 批量更新目标表中的slm_id
        // slm_busobject_service_target_sql
        // .add("UPDATE "
        // + apply_object_rely_table_name
        // +
        // " c INNER JOIN  slm_busobject_service_target b  ON b.apply_object_id=c.id "
        // +
        // " INNER JOIN slm_service_target t ON b.service_target_id=t.id "
        // +
        // " INNER JOIN slm_service_agreement ag ON t.agreement_id=ag.id  "
        // +
        // " SET slm_id= ag.id ,slm_name=ag.name  WHERE slm_id IS NULL ");
        // } else {
        // oracle
        // 批量更新目标表中的slm_id
        // slm_busobject_service_target_sql
        // .add("UPDATE "
        // + apply_object_rely_table_name
        // +
        // " c SET (slm_id ,slm_name)=(SELECT ag.id,ag.name FROM slm_busobject_service_target b "
        // + " INNER JOIN slm_service_agreement ag ON b.slm_id=ag.id  "
        // +
        // " WHERE b.apply_object_id=c.id  AND ROWNUM = 1 ) WHERE  slm_id IS NULL ");
        // }

        /*
         * 更新关联实体的sla_status字段
         */
        slm_busobject_service_target_sql.add("UPDATE "
            + apply_object_rely_table_name + " a SET sla_status=1  "
            + " WHERE ( a.sla_status=0) AND EXISTS "
            + " (SELECT 1 FROM slm_busobject_service_target b  "
            + " WHERE  a.id=b.apply_object_id AND  b.status='异常') ");

        // 启动服务
        slm_busobject_service_target_sql
            .add("UPDATE slm_busobject_service_target a SET started=1 ,start_time="
                + nowSql
                + ",update_time="
                + nowSql
                + "  WHERE EXISTS (SELECT 1  "
                + "  FROM  slm_service_target b,"
                + apply_object_rely_table_name
                + "  c  "
                + " WHERE a.service_target_id=b.id AND  a.apply_object_id = c.id  AND a.stoped=0 AND a.started=0 ) ");
        // 关闭计算
        /*
         * slm_busobject_service_target_sql
         * .add("UPDATE slm_busobject_service_target a SET  stoped=1,finish_time="
         * + nowSql + ",actual_value=current_value" +
         * "  WHERE ( stoped=0  AND  EXISTS  (SELECT 1 FROM  slm_service_target b,"
         * + apply_object_rely_table_name +
         * " c  WHERE  a.service_target_id=b.id AND a.apply_object_id = c.id  AND started=1) ) "
         * );
         */

        // 自动升级
        autoUpgrade(apply_object_rely_table_name);
      }
    }

    // 计算时间
    slm_busobject_service_target_sql
        .add("UPDATE slm_busobject_service_target a"
            + " SET update_time="
            + nowSql
            + ",  a.cumulative_time=a.cumulative_time+"
            + interval
            + ", a.current_value = CONCAT(CONCAT( FLOOR(a.cumulative_time / 3600),':'),FLOOR(mod(a.cumulative_time ,3600) / 60)), "
            + "a.status = ( CASE WHEN  plan_value_sec  < cumulative_time   THEN '异常'  ELSE '正常'  END  )"
            + "  WHERE  a.stoped=0 AND EXISTS( SELECT 1 FROM "
            + "  slm_service_target b,"
            + apply_object_rely_table_name
            + " c  WHERE   a.service_target_id=b.id AND a.apply_object_id = c.id  AND a.started=1 ) AND a.slm_id IN("
            + argeement_ids + ")");

    // 发送slm告警
    slm_busobject_service_target_sql
        .add("INSERT INTO slm_alarm_message_history ( slm_busobject_id,  slm_alarm_setting_id,apply_object_id,sended)"
            + " SELECT DISTINCT a.id,  b.id AS bid,a.apply_object_id, 0 AS sended FROM slm_busobject_service_target a "
            + " INNER JOIN slm_alarm_setting b  ON a.service_target_id = b.service_target_id "
            + " LEFT JOIN slm_alarm_message_history c  ON a.id = c.slm_busobject_id  AND b.id = c.slm_alarm_setting_id  "
            + " WHERE a.stoped = 0 AND a.started=1 AND c.id IS NULL  AND a.plan_value_sec - a.cumulative_time + b.distance <= 0 ");

    StopWatch sw = new StopWatch();
    sw.start();
    String[] sql = new String[slm_busobject_service_target_sql.size()];
    sql = slm_busobject_service_target_sql.toArray(sql);
    jdbcTemplate.batchUpdate(slm_busobject_service_target_sql.toArray(sql));

    sw.stop();
    // long nano = sw.getNanoTime();
    // System.out.println(nano);
    sendMessage();
  }

  // 针对普通方法调用的方法
  public static final void sendMessage() {
    JdbcTemplate jdbcTemplate = ContextHolder.getSpringBean("jdbcTemplate");

    List<Map<String, Object>> mh = jdbcTemplate
        .queryForList("SELECT  a.slm_alarm_setting_id,a.apply_object_id,b.title,b.type,b.description,b.content,b.send_way"
            + " FROM slm_alarm_message_history a"
            + " INNER JOIN slm_alarm_setting b  ON a.slm_alarm_setting_id=b.id WHERE sended=0");
    jdbcTemplate
        .update("UPDATE slm_alarm_message_history SET sended=1 WHERE sended=0");
    List<AppMessage> mqs = new ArrayList<>();
    Template t = new Template();
    for (Map<String, Object> h : mh) {
      if (h.get("apply_object_id") == null)
        continue;
      String oId = h.get("apply_object_id").toString();
      String content = h.get("content").toString();
      String title = h.get("title").toString();
      String send_way = h.get("send_way").toString();

      String[] sendWays = send_way.split(",");

      List<Map<String, Object>> list = jdbcTemplate
          .queryForList("SELECT * FROM icd_incident  WHERE id='" + oId + "'");
      if (list.size() == 0)
        continue;
      Map<String, Object> o = list.get(0);
      Map<String, Object> context = new HashMap<>();
      context.put("bpmBusinessModel", o);
      t.setContext(context);

      t.setSource(content);

      String mContent;
      try {
        mContent = t.render();
      } catch (TemplateException e) {
        mContent = title;
      }

      // 发送到对象
      List<Map<String, Object>> mbs = jdbcTemplate
          .queryForList("SELECT assign_type,cmp_ids FROM slm_alarm_object a WHERE relation_id='"
              + h.get("slm_alarm_setting_id").toString() + "'");

      for (Map<String, Object> mb : mbs) {

        Map<String, IUser> mapUsers = new HashMap<String, IUser>();

        MessageUserUtils.addToReceiver(mapUsers, mb, oId,
            (String) o.get("project_id"), "incidentProcess");

        for (String k : mapUsers.keySet()) {

          IUser u = mapUsers.get(k);

          for (String st : sendWays) {
            AppMessage mq = new AppMessage();

            mq.setContent(mContent);
            mq.setTitle(title);
            mq.setContent(mContent);
            mq.setReceiver(u.getUsername());
            mq.setReceiverAddress(u.getEmail());
            mq.setMessageType(st);
            mq.setSourceId(oId);
            mq.setSender("admin");
            mq.setSenderId("admin");
            mqs.add(mq);
          }
        }

      }

    }
    t = null;

    if (mqs.size() > 0) {
      AppMessageService appMessageService = ContextHolder
          .getSpringBean("appMessageService");
      appMessageService.addToMessageQuery(mqs);

    }

  }

  /**
   * 自动升级,对启用自动升级的流程，当超时异常将自动升级到指定的节点
   * 
   * @author gaojy
   * @since 3.2 edit at 20150727
   */
  public void autoUpgrade(String slm_rely_table_name) {
    String sql = "SELECT a.process_id,c.is_auto_upgrade,c.auto_upgrade_node_id,b.id service_target_id FROM "
        + slm_rely_table_name
        + " a INNER JOIN slm_busobject_service_target b ON a.id=b.apply_object_id"
        + " INNER JOIN slm_service_target c ON b.service_target_id=c.id"
        + " WHERE  b.status='异常' AND a.status<>'已关闭' AND c.is_auto_upgrade='1' and b.ishad_upgrade='0'";

    List<Map<String, Object>> autoUpgradeList = jdbcTemplate.queryForList(sql);
    for (Map<String, Object> map : autoUpgradeList) {
      String processInstanceId = map.get("process_id").toString();
      String activityId = map.get("auto_upgrade_node_id").toString();
      String serviceTargetId = map.get("service_target_id").toString();
      String exeUsername = "admin";
      String memo = "";
      processEngine.getManagementService().executeCommand(
          new JumpCmd(processInstanceId, activityId, exeUsername, memo));

      String sql2 = "UPDATE slm_busobject_service_target SET ishad_upgrade='1' where id='"
          + serviceTargetId + "'";
      jdbcTemplate.update(sql2);
    }
  }
}
